package com.gdust.spzx.common.log.utils;

import com.alibaba.fastjson.JSON;
import com.gdust.spzx.common.log.annotation.Log;
import com.gdust.hzx.model.entity.system.SysOperLog;
import com.gdust.hzx.utils.AuthContextUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.http.HttpMethod;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * ClassName: LogUtil
 * Package: com.gdust.spzx.common.utils
 * Description: 日志工具类，用于在操作方法调用前后对日志数据进行处理。
 *
 * @Author syun
 * @Create 2024/12/24 20:40
 * @Version 1.0
 */
public class LogUtil {
    /**
     * 在操作方法执行后调用，处理日志记录的响应数据和状态。
     *
     * @param sysLog    自定义注解 @Log，提供日志记录的配置信息
     * @param proceed   操作方法的返回结果
     * @param sysOperLog 日志实体，用于封装操作日志信息
     * @param status    操作状态，0 表示成功，1 表示失败
     * @param errorMsg  错误消息，在操作失败时记录
     */
    public static void afterHandleLog(Log sysLog, Object proceed,
                                     SysOperLog sysOperLog, int status ,
                                     String errorMsg) {
        // 判断是否需要保存响应数据
        if(sysLog.isSaveResponseData()) {
            // 设置响应结果
            sysOperLog.setJsonResult(JSON.toJSONString(proceed));
        }
        // 设置操作状态
        sysOperLog.setStatus(status);
        // 设置错误消息
        sysOperLog.setErrorMsg(errorMsg);
    }

    /**
     * 在操作方法执行前调用，处理日志记录的请求数据和相关信息。
     *
     * @param sysLog    自定义注解 @Log，提供日志记录的配置信息
     * @param joinPoint 切入点对象，包含目标方法的详细信息
     * @param sysOperLog 日志实体，用于封装操作日志信息
     */
    public static void beforeHandleLog(Log sysLog,
                                       ProceedingJoinPoint joinPoint,
                                       SysOperLog sysOperLog) {

        // 设置操作模块名称和操作人类型
        sysOperLog.setTitle(sysLog.title());// 设置操作模块标题
        sysOperLog.setOperatorType(sysLog.operatorType().name());// 设置操作人类型

        // 获取目标方法的签名和详细信息
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature() ;
        Method method = methodSignature.getMethod();
        sysOperLog.setMethod(method.getDeclaringClass().getName());// 设置方法名称

        // 获取请求上下文和请求信息
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)
                RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        sysOperLog.setRequestMethod(request.getMethod());// 设置请求方法类型（GET/POST等）
        sysOperLog.setOperUrl(request.getRequestURI()); // 设置请求的URL
        sysOperLog.setOperIp(request.getRemoteAddr());// 设置请求的IP地址


        // 判断是否需要保存请求数据
        if(sysLog.isSaveRequestData()) {
            String requestMethod = sysOperLog.getRequestMethod();
            // 如果是 PUT 或 POST 请求，记录请求参数
            if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
                // 获取方法参数并转为字符串
                String params = Arrays.toString(joinPoint.getArgs());
                // 设置请求参数
                sysOperLog.setOperParam(params);
            }
        }
        // 设置操作人名称
        sysOperLog.setOperName(AuthContextUtil.get().getUserName());
    }


}
